import { useServers } from "@/stores/servers";
import type connection from "./connection";
import { disconnected, handle } from "./eventFunctions";
import type requestMessage from "./requestMessage";
import type responseMessage from "./responseMessage";
import { jsonToRes, ResponseType } from "./responseMessage";
import { reqToJson, RequestType } from "./requestMessage";
import { sendMessage } from "../message";


export default class websocket implements connection {
    websocket?: WebSocket
    name: string;
    workable: boolean
    sendingMessages: { [index: string]: number } = {}
    sendMessage(message: requestMessage) {
        if (this.websocket == undefined) {
            return false
        }
        let msgId: string | undefined
        while (Object.keys(this.sendingMessages).includes(msgId ?? '') || msgId == undefined) {
            msgId = Math.floor(Math.random() * 100000000).toString()
        }
        message.msgId = msgId
        this.sendingMessages[msgId] = setInterval(() => {
            if (this.websocket) {
                this.websocket.send(reqToJson(message))
            } else {
                clearInterval(this.sendingMessages[message.body as string])
                delete this.sendingMessages[message.body as string]
            }
        }, 300)
        return true
    }
    handle: (message: responseMessage) => void;
    disconnected: (connection: connection) => void;
    open() {
        const servers = useServers()

        return new Promise<void>((resolve, reject) => {
            this.websocket = new WebSocket(`${servers.roomServer}/ws/${this.room}/${this.userName}/${this.enterPassword || "-"}`);
            this.websocket.onmessage = (evt) => {
                let res = jsonToRes(evt.data)
                if (res.type != ResponseType.RECOGNIZE_MESSAGE) {
                    this.handle(res);
                    let req: requestMessage = {
                        body: res.msgId,
                        type: RequestType.RECOGNIZE_MESSAGE,
                        receiver: ''
                    }
                    this.websocket?.send(reqToJson(req))
                } {
                    clearInterval(this.sendingMessages[res.body as string])
                    delete this.sendingMessages[res.body as string]
                }
            };
            this.websocket.onopen = () => {
                sendMessage("已连接到房间","success");
                this.workable = true;
                resolve();
            };
            this.websocket.onclose = (ev) => {
                sendMessage(ev.reason??"退出房间","warn");
                this.websocket = undefined;
                this.workable = false;
                this.disconnected(this);
                reject()

            };
            this.websocket.onerror = () => {
                sendMessage("连接失败","error");

                this.websocket = undefined;
                this.workable = false;
                this.disconnected(this);
                reject()


            };
        });
    };
    close() {
        if (this.websocket == undefined) {
            return false
        }
        this.workable = false
        this.websocket.close()
        return true
    };
    room: string
    userName: string
    enterPassword: string
    constructor(room: string, userName: string, enterPassword: string) {
        this.name = ''
        this.handle = handle
        this.disconnected = disconnected
        this.userName = userName
        this.enterPassword = enterPassword
        this.room = room
        this.workable = false
    }
}